﻿namespace AR.Model
{
    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.ServiceModel.DomainServices.Client;
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using AR.Entities;
    using AR.Web.Resources;
    using AR.Web.Services;
    using System.Linq;
    //  using AR.CientFramework;
    using System.Collections.ObjectModel;
    using AR.Web;
    using AR.CustomEntities;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using System.Windows;
    using AR.Helpers;
    using System.Text;
    using AR.ViewModel.Candidat;
    using System.Windows.Controls;
    /// <summary>
    /// This internal entity is used to ease the binding between the UI controls (DataForm and the label displaying a validation error) and the log on credentials entered by the user.
    /// </summary>
    public class CandidatModel
    {
        readonly CandidatContext candidatcontext;
        readonly EntretienTechniqueContext Testcontext;
        readonly EntretienOraleContext entretiencontext;
        private static Action<bool, CANDIDAT> iscodecandidatvalid = null;
        public static void SetDelegate(Action<bool,CANDIDAT> action)
        {
            iscodecandidatvalid = action;
        }
        public CandidatModel()
        {
                        
                candidatcontext = new CandidatContext();
                entretiencontext = new EntretienOraleContext();
                Testcontext = new EntretienTechniqueContext();                
        }
        public EntitySet<CANDIDAT> GetCandidats()
        {
            var query = candidatcontext.GetCANDIDATQuery();
            candidatcontext.Load(query);
            return candidatcontext.CANDIDATs;
        }     
        public void isCandidatCodeValid(string Code)
        {
            bool isvalid=false;
            var query = candidatcontext.VerifyCANDIDATCodeQuery(Code);
            candidatcontext.Load(query).Completed += (sender, e) =>
            {
              if(candidatcontext.CANDIDATs.Any(c=> ResultatEntretienTechnique.idcandidat != c.ID_CANDIDAT))
                  iscodecandidatvalid(true,candidatcontext.CANDIDATs.FirstOrDefault());
                else
                  iscodecandidatvalid(false,null);
            };          
        }
        public EntitySet<PRACTICE> GetPractices()
        {
            var query = candidatcontext.GetPRACTICEQuery();
            candidatcontext.Load(query);
            return candidatcontext.PRACTICEs;
        }
        public EntitySet<CANDIDAT> GetCandidatsEntOrale()
        {
            candidatcontext.Load(candidatcontext.GetCANDIDATQuery());
            entretiencontext.Load(entretiencontext.GetENTERTIEN_ORALEQuery());

            var CandidatEntr = from can in candidatcontext.CANDIDATs
                               where !(from ent in entretiencontext.ENTRETIEN_ORALEs
                                       select ent.ID_CANDIDAT).Contains(can.ID_CANDIDAT)
                               select can;

            EntitySet<CANDIDAT> result = new EntitySet<CANDIDAT>();
            foreach (CANDIDAT item in CandidatEntr)
            {
                result.Add(item);
            }
            candidatcontext.CANDIDATs.Clear();
            var query = candidatcontext.GetCANDIDATQuery();
           // candidatcontext.Load(CandidatEntr);
            return result;
        }
        public EntitySet<CANDIDAT> FindCandidat(SearchCandidatCritaria critaria)
        {
            candidatcontext.CANDIDATs.Clear();
            //var query = candidatcontext.GetCANDIDATQuery();
            //candidatcontext.Load(query);
            //return candidatcontext.CANDIDATs;
           // ObservableCollection<CANDIDAT> candidatresult = new ObservableCollection<CANDIDAT>();
          //  var query = candidatcontext.FindCandidatQuery(critaria.Nom, critaria.Prenom, critaria.Email, critaria.NiveauEtudes, critaria.CandidatDateNaissanceOperator, critaria.DateNaissance, critaria.NiveauExp);
            if (critaria.IdTags != null && critaria.IdTags.Count() > 0)
            {
                var query = candidatcontext.GetCANDIDATByTagIdsQuery(critaria.IdTags);
                if (!string.IsNullOrEmpty(critaria.Nom))
                    query = query.Where(c => c.NOM.Contains(critaria.Nom));
                if (!string.IsNullOrEmpty(critaria.Prenom))
                    query = query.Where(p => p.PRENOM.Contains(critaria.Prenom));
                if (!string.IsNullOrEmpty(critaria.Email))
                    query = query.Where(p => p.EMAIL.Contains(critaria.Email));
                if (critaria.ID_PRACTICE > 0)
                    query = query.Where(p => p.ID_PRACTICE == critaria.ID_PRACTICE);
                if (critaria.ID_ETUDES > 0)
                    query = query.Where(p => p.ID_ETUDE == critaria.ID_ETUDES);
                if (critaria.ID_EXPERIENCE > 0)
                    query = query.Where(p => p.ID_EXPERIENCE == critaria.ID_EXPERIENCE);
                if (!string.IsNullOrEmpty(critaria.DernierEmployeur))
                    query = query.Where(p => p.DERNIER_EMPLOYEUR.Contains(critaria.DernierEmployeur));
                if (!string.IsNullOrEmpty(critaria.Tel))
                    query = query.Where(p => p.TEL.Contains(critaria.Tel));

                candidatcontext.Load(query).Completed +=(sender, arg)=>
                {
                    (Application.Current.RootVisual as BusyIndicator).IsBusy = false;
                }; 
            }
            else
            {
                var query = candidatcontext.GetCANDIDATQuery();

                if (!string.IsNullOrEmpty(critaria.Nom))
                    query = query.Where(c => c.NOM.Contains(critaria.Nom));
                if (!string.IsNullOrEmpty(critaria.Prenom))
                    query = query.Where(p => p.PRENOM.Contains(critaria.Prenom));
                if (!string.IsNullOrEmpty(critaria.Email))
                    query = query.Where(p => p.EMAIL.Contains(critaria.Email));
                if (critaria.ID_PRACTICE > 0)
                    query = query.Where(p => p.ID_PRACTICE == critaria.ID_PRACTICE);
                if (critaria.ID_ETUDES > 0)
                    query = query.Where(p => p.ID_ETUDE == critaria.ID_ETUDES);
                if (critaria.ID_EXPERIENCE > 0)
                    query = query.Where(p => p.ID_EXPERIENCE == critaria.ID_EXPERIENCE);
                //if (!string.IsNullOrEmpty(critaria.NiveauExp.ToString()))
                //    query = query.Where(p => p.NIVEAU_EXPERIENCE >= critaria.NiveauExp);
                if (!string.IsNullOrEmpty(critaria.DernierEmployeur))
                    query = query.Where(p => p.DERNIER_EMPLOYEUR.Contains(critaria.DernierEmployeur));
                if (!string.IsNullOrEmpty(critaria.Tel))
                    query = query.Where(p => p.TEL.Contains(critaria.Tel));

                candidatcontext.Load(query).Completed += (sender, arg) =>
                {
                    (Application.Current.RootVisual as BusyIndicator).IsBusy = false;
                }; 
            }
            EntitySet<CANDIDAT> candidats = candidatcontext.CANDIDATs;
            return candidatcontext.CANDIDATs;
        }
        public void SubmitChanges()
        {
            candidatcontext.SubmitChanges();
        }
        public EntitySet<CANDIDAT> GetCandidatsEntretien()
        {
            candidatcontext.CANDIDATs.Clear();
            var query = candidatcontext.FindCandidatEntretienQuery();
            candidatcontext.Load(query);
            return candidatcontext.CANDIDATs;
        }
        public void AddCandidat(CANDIDAT candidat, List<TAG> tags)
        {
            this.candidatcontext.CANDIDATs.Add(candidat);
            this.candidatcontext.SubmitChanges().Completed += (sender2, ev) =>
            {
                //SupressionCandidatTags(candidat.ID_CANDIDAT, tags);
                foreach (TAG tag in tags)
                {
                    if (tag.ID_TAG != 0)
                    {
                        AjoutCandidatTag(candidat.ID_CANDIDAT, tag.ID_TAG);
                    }
                    else
                    {
                        this.candidatcontext.TAGs.Add(tag);
                        this.candidatcontext.SubmitChanges().Completed += (sender3, ev3) =>
                        {
                            int idTag = this.candidatcontext.TAGs.Where(t => t.NOM == tag.NOM).FirstOrDefault().ID_TAG;
                            AjoutCandidatTag(candidat.ID_CANDIDAT, idTag);
                        };
                    }
                }
                Tools.AfficheNotificationFlash(string.Format("Le candidat {0} {1} a été crée avec succès", candidat.NOM, candidat.PRENOM));
                HistoriserCandidat(candidat);
                NavigationService.Navigate("/ListeCandidats");
            };
        }
        public void AddCandidatCSV(ObservableCollection<CSVCandidat> CSVCandidats)
         {
             CANDIDAT Candidat= null;
             foreach (var CSVCandidat in CSVCandidats)
             {
                      Candidat = new CANDIDAT()
                     {
                         NOM = CSVCandidat.Nom,
                         PRENOM = CSVCandidat.Prenom,
                         SALAIRE_ACTUELLE = CSVCandidat.Salaire_Actuelle,
                         SALAIRE_DEMANDE = CSVCandidat.Salaire_Demande,
                         PREAVIS = CSVCandidat.Preavis,
                         EMAIL = CSVCandidat.Email,
                         TEL = CSVCandidat.Tel,
                         DATE_TEST_TECHNIQUE = CSVCandidat.DateTestTechnique,
                         DATE_CREATION = DateTime.Now,
                         USER_NAME = WebContext.Current.User.Name,
                         CODE_TEST = this.RandomString(7),
                         ID_STATUT = 6,
                         ID_ETUDE= CSVCandidat.IdEtudes,
                         ID_EXPERIENCE= CSVCandidat.IdExp
                         

                     };
                      this.candidatcontext.CANDIDATs.Add(Candidat);
                

             }
             this.candidatcontext.SubmitChanges().Completed += (sender2, ev) =>
                {
                    HistoriserCandidat(Candidat);
                };
           
         }
        public void UpdateCandidat(CANDIDAT candidat, string cvpath, List<TAG> tags)
        {
           var query = candidatcontext.GetCandidatByIDQuery(candidat.ID_CANDIDAT);
                candidatcontext.Load(query).Completed += (sender2, ev) =>
                {
                    CANDIDAT Oldcandidat = candidatcontext.CANDIDATs.SingleOrDefault();
                    Oldcandidat.EMAIL = candidat.EMAIL;
                    Oldcandidat.TEL = candidat.TEL;
                    if (Oldcandidat.CV != cvpath)
                    Oldcandidat.CV = candidat.CV;
                    Oldcandidat.DATE_TEST_TECHNIQUE = candidat.DATE_TEST_TECHNIQUE;
                    Oldcandidat.DATE_INTEGRATION = candidat.DATE_INTEGRATION;
                    Oldcandidat.NOM = candidat.NOM;
                    Oldcandidat.PRENOM = candidat.PRENOM;
                    Oldcandidat.DATENAISSANCE = candidat.DATENAISSANCE;
                    Oldcandidat.DERNIER_EMPLOYEUR = candidat.DERNIER_EMPLOYEUR;
                    Oldcandidat.PREAVIS = candidat.PREAVIS;
                    Oldcandidat.GCM_ESTIMEE_RH = candidat.GCM_ESTIMEE_RH;
                    Oldcandidat.REMARQUE = candidat.REMARQUE;
                    Oldcandidat.DATE_ENTRETIEN_TECHNIQUE = candidat.DATE_ENTRETIEN_TECHNIQUE;
                    Oldcandidat.DATE_ENTRETIEN_RH = candidat.DATE_ENTRETIEN_RH;
                    Oldcandidat.SALAIRE_ACTUELLE = candidat.SALAIRE_ACTUELLE;
                    Oldcandidat.SALAIRE_DEMANDE = candidat.SALAIRE_DEMANDE;
                    Oldcandidat.ID_PRACTICE = candidat.ID_PRACTICE;
                    Oldcandidat.ID_ETUDE = candidat.ID_ETUDE;
                    Oldcandidat.ID_EXPERIENCE = candidat.ID_EXPERIENCE;
                    Oldcandidat.ID_POSTE = candidat.ID_POSTE;
                    Oldcandidat.ID_PROJET = candidat.ID_PROJET;
                    if (candidat.ID_TEST > 0)
                        Oldcandidat.ID_TEST = candidat.ID_TEST;
                   // candidat.ID_STATUT = 2;
                    candidatcontext.SubmitChanges().Completed += (sender, args) =>
                    {
                        SupressionCandidatTags(candidat.ID_CANDIDAT, tags);
                        foreach (TAG tag in tags)
                        {
                            if (tag.ID_TAG != 0)
                            {
                                AjoutCandidatTag(candidat.ID_CANDIDAT, tag.ID_TAG);
                            }
                            else
                            {
                                this.candidatcontext.TAGs.Add(tag);
                                this.candidatcontext.SubmitChanges().Completed += (sender3, ev3) =>
                                {
                                    int idTag = this.candidatcontext.TAGs.Where(t => t.NOM == tag.NOM).FirstOrDefault().ID_TAG;
                                    AjoutCandidatTag(candidat.ID_CANDIDAT, idTag);
                                    this.candidatcontext.SubmitChanges();
                                };
                            }
                        }
                        AR.Views.ToastNotification Toast = AR.Views.ToastNotification.CreateToast(4);
                        Tools.AfficheNotificationFlash(string.Format("Le candidat {0} {1} a été modifié avec succès", candidat.NOM, candidat.PRENOM));
                        
                        HistoriserCandidat(candidat);
                        NavigationService.Navigate("/ListeCandidats");
                    };
                };
        }      
        public EntitySet<POSTE> GetPostes()
        {
            var query = candidatcontext.GetPOSTEQuery();
            candidatcontext.Load(query);
            return candidatcontext.POSTEs;
        }
        public EntitySet<PROJET> GetProjets()
        {
            var query = candidatcontext.GetPROJETQuery();
            candidatcontext.Load(query);
            return candidatcontext.PROJETs;

        }
        public EntitySet<NIVEAU_ETUDE> GetNiveauEtudes()
        {
            var query = candidatcontext.GetNIVEAU_ETUDEQuery();
            candidatcontext.Load(query);
            return candidatcontext.NIVEAU_ETUDEs;
        }
        public EntitySet<NIVEAU_EXPERIENCE> GetNiveauExperience()
        {
            var query = candidatcontext.GetNIVEAU_EXPERIENCEQuery();
            candidatcontext.Load(query);
            return candidatcontext.NIVEAU_EXPERIENCEs;

        }
        public EntitySet<CANDIDAT> GetCandidatsResultat()
        {
            candidatcontext.CANDIDATs.Clear();
            var query = candidatcontext.FindCandidatResultatQuery();
            candidatcontext.Load(query);
            return candidatcontext.CANDIDATs;
        }
        public EntitySet<STATUT_CANDIDAT> GetStatutsCandidat()
        {
            var query = candidatcontext.GetSTATUT_CANDIDATQuery();
            candidatcontext.Load(query);
            return candidatcontext.STATUT_CANDIDATs;
        }
        public EntitySet<TEST_TECHNIQUE> GetTestsTechniques()
        {
            var query = Testcontext.GetTEST_TECHNIQUEQuery();
            Testcontext.Load(query);
            return Testcontext.TEST_TECHNIQUEs;
        }
        public EntitySet<CANDIDAT_HISTORIQUE> FindCandidatHistorique(int ID_CANDIDAT)
        {
            candidatcontext.CANDIDAT_HISTORIQUEs.Clear();
            var query = candidatcontext.GetCANDIDAT_HISTORIQUEQuery().Where(_ => _.ID_CANDIDAT == ID_CANDIDAT);

            candidatcontext.Load(query);
            return candidatcontext.CANDIDAT_HISTORIQUEs;
        }

        public bool HistoriserCandidat(CANDIDAT candidat)
        {
            try
            {
                CANDIDAT_HISTORIQUE candidatHisto = new CANDIDAT_HISTORIQUE();
                candidatHisto.ID_CANDIDAT = candidat.ID_CANDIDAT;
                candidatHisto.NOM = candidat.NOM;
                candidatHisto.PRENOM = candidat.PRENOM;
                candidatHisto.DATENAISSANCE = candidat.DATENAISSANCE;
                candidatHisto.GCM_ESTIMEE_RH = candidat.GCM_ESTIMEE_RH;
                candidatHisto.GCM_ESTIMEE_SM = candidat.GCM_ESTIMEE_SM;
                candidatHisto.DERNIER_EMPLOYEUR = candidat.DERNIER_EMPLOYEUR;
                candidatHisto.SALAIRE_ACTUELLE = candidat.SALAIRE_ACTUELLE;
                candidatHisto.SALAIRE_DEMANDE = candidat.SALAIRE_DEMANDE;
                candidatHisto.PREAVIS = candidat.PREAVIS;
                candidatHisto.TEL = candidat.TEL;
                candidatHisto.EMAIL = candidat.EMAIL;
                candidatHisto.DATE_ENTRETIEN_TECHNIQUE = candidat.DATE_ENTRETIEN_TECHNIQUE;
                candidatHisto.DATE_ENTRETIEN_RH = candidat.DATE_ENTRETIEN_RH;
                candidatHisto.REMARQUE = candidat.REMARQUE;
                candidatHisto.POSTE = candidatcontext.POSTEs.Where(p=>p.IDPOSTE  == candidat.ID_POSTE).FirstOrDefault().POST;
                candidatHisto.PROJET = candidatcontext.PROJETs.Where(p => p.IDPROJET == candidat.ID_PROJET).FirstOrDefault().PROJET1;
                candidatHisto.CV = candidat.CV;
                candidatHisto.PRACTICE = candidatcontext.PRACTICEs.Where(p => p.ID_PRACTICE == candidat.ID_PRACTICE).FirstOrDefault().PRACTICE1;
                candidatHisto.CODE_TEST = candidat.CODE_TEST;
                candidatHisto.DATE_CREATION = candidat.DATE_CREATION;
                candidatHisto.STATUT_CANDIDAT = candidatcontext.STATUT_CANDIDATs.Where(s => s.ID_STATUT == candidat.ID_STATUT).FirstOrDefault().INTITULE;
                candidatHisto.ETUDE = candidatcontext.NIVEAU_ETUDEs.Where(ne => ne.ID_ETUDE == candidat.ID_ETUDE).FirstOrDefault().INTITULE;
                candidatHisto.EXPERIENCE = candidatcontext.NIVEAU_EXPERIENCEs.Where(ne => ne.ID_EXPERIENCE == candidat.ID_EXPERIENCE).FirstOrDefault().INTITULE;
                candidatHisto.USER_NAME = candidat.USER_NAME;
                candidatHisto.ETAT_ENTRETIEN_ORALE = candidat.ETAT_ENTRETIEN_ORALE;
                candidatHisto.ETAT_ENTRETIEN_ECRIT = candidat.ETAT_ENTRETIEN_ECRIT;
                candidatHisto.TEST = Testcontext.TEST_TECHNIQUEs.Where(tt => tt.ID_TEST == candidat.ID_TEST).FirstOrDefault().TEST_INTITULE; 
                candidatHisto.PHOTO = candidat.PHOTO;
                candidatHisto.ORDRE = candidat.ORDRE;
                candidatHisto.NOTE_TEST = candidat.NOTE_TEST;
                candidatHisto.DUREE_TEST = candidat.DUREE_TEST;
                candidatHisto.ACTIVE = candidat.ACTIVE;
                candidatHisto.DATE_MODIFICATION = DateTime.Now;

                candidatcontext.CANDIDAT_HISTORIQUEs.Add(candidatHisto);
                candidatcontext.SubmitChanges();
            }
            catch (Exception ex)
            {
                return false;
            }
            
            return true;
        }

        public EntitySet<TAG> GetTags()
        {
            var query = candidatcontext.GetTAGQuery();
            candidatcontext.Load(query);
            return candidatcontext.TAGs;
        }
        public EntitySet<CANDIDAT_TAG> GetCandidatTagsByIdCandidat(int id)
        {
            var query = candidatcontext.GetTAGByIdCandidatQuery(id);
            candidatcontext.Load(query);
            return candidatcontext.CANDIDAT_TAGs;
        }
        public EntitySet<CANDIDAT_TAG> GetCandidatTags()
        {
            var query = candidatcontext.GetCANDIDAT_TAGQuery();
            candidatcontext.Load(query);
            return candidatcontext.CANDIDAT_TAGs;
        }

        public bool AjoutCandidatTag(int idCandidat, int idTag)
        {
            //CANDIDAT candidatTrouve = candidatcontext.CANDIDATs.Where(w => w.ID_CANDIDAT == idCandidat).First();
            CANDIDAT_TAG nCandidatTag = new CANDIDAT_TAG();
            nCandidatTag.ID_CANDIDAT = idCandidat;
            nCandidatTag.ID_TAG = idTag;
            candidatcontext.CANDIDAT_TAGs.Add(nCandidatTag);
            //candidatTrouve.CANDIDAT_TAG.Add(nCandidatTag);
            return true;
        }
        public bool SupressionCandidatTags(int idCandidat, List<TAG> tags)
        {
            CANDIDAT candidatTrouve = candidatcontext.CANDIDATs.Where(w => w.ID_CANDIDAT == idCandidat).First();
            List<CANDIDAT_TAG> liste = candidatTrouve.CANDIDAT_TAG.Where(t=> tags.Where(s=>t.ID_TAG!=s.ID_TAG).Count()>0).ToList();
            foreach (CANDIDAT_TAG item in liste)
            {
                candidatcontext.CANDIDAT_TAGs.Remove(item);
            }
            return true;
        }
        private string RandomString(int size)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            if (!CreationCandidatViewModel.usedtestcode.Contains(builder.ToString()))
            {

                CreationCandidatViewModel.usedtestcode.Add(builder.ToString().ToLower());
                return builder.ToString().ToLower();

            }
            else
            {
                return this.RandomString(size);
            }
        }
    }

}
